package com.wj.service.impl;

import com.wj.account.BalanceInfo;
import com.wj.dao.BalanceDao;
import com.wj.entity.Balance;
import com.wj.filter.AccessContext;
import com.wj.service.IBalanceService;
import com.wj.vo.LoginUserInfo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Objects;

/**
 *  余额相关服务接口实现类
 */
@Slf4j
@Service
@Transactional(rollbackFor = Exception.class)
public class BalanceServiceImpl implements IBalanceService {

    private final BalanceDao balanceDao;

    public BalanceServiceImpl(BalanceDao balanceDao) {
        this.balanceDao = balanceDao;
    }

    @Override
    public BalanceInfo getCurrentUserBalanceInfo() {
        LoginUserInfo loginUserInfo = AccessContext.getLoginUserInfo();
        BalanceInfo balanceInfo = new BalanceInfo(loginUserInfo.getId(), 0L);

        Balance balance = balanceDao.findByUserId(loginUserInfo.getId());
        if (Objects.nonNull(balance)) {
            balanceInfo.setBalance(balance.getBalance());
        }else {
            //如果还没有用户余额记录，这里创建出来，余额设定为0即可
            Balance newBalance = new Balance();
            newBalance.setUserId(loginUserInfo.getId());
            newBalance.setBalance(0L);
            log.info("init user balance record: [{}]", balanceDao.save(newBalance).getId());
        }

        return balanceInfo;
    }

    @Override
    public BalanceInfo deductBalance(BalanceInfo balanceInfo) {
        LoginUserInfo loginUserInfo = AccessContext.getLoginUserInfo();
        // 扣减用户余额的一个基本原则: 扣减额 <= 当前用户余额
        Balance balance = balanceDao.findByUserId(loginUserInfo.getId());
        if (Objects.isNull(balance) || balance.getBalance() < balanceInfo.getBalance()){
            throw new RuntimeException("user balance is not enough");
        }

        Long sourceBalance = balance.getBalance();
        balance.setBalance(balance.getBalance() - balanceInfo.getBalance());
        log.info("deduct balance: [{}], [{}], [{}]",
                balanceDao.save(balance).getId(),sourceBalance,balanceInfo.getBalance());

        return new BalanceInfo(balance.getUserId(),balance.getBalance());
    }
}
